﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Rj.PersonnelVerification.Server.Constant.JsonConverter;
using Rj.PersonnelVerification.Server.DataBaseContext;
using Rj.PersonnelVerification.Server.DataBaseContext.Entities;
using Rj.PersonnelVerification.Server.Models;
using Rj.PersonnelVerification.Server.Models.VerificationNode;
using Rj.PersonnelVerification.Server.Repositories;
using Rj.PersonnelVerification.Server.Utils;
using Rj.PersonnelVerification.Shared.Models.Request;
using Rj.PersonnelVerification.Shared.Models.Response;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Text.Encodings.Web;
using static MudBlazor.CategoryTypes;
using Microsoft.Extensions.Logging;
using Rj.PersonnelVerification.Server.Timeer;

namespace Rj.PersonnelVerification.Server.Servers.Impl
{
    public class PersonVerficaService: IPersonVerficaService
    {
        private IHisRepository hisRepository;
        private IVerificationRepository verificationRepository;
        private IMapper mapper;
        private HisDbContext dbContext;
        private IHttpContextAccessor httpContextAccessor;

        private  LogService _logService;


        private static readonly JsonSerializerOptions options = new JsonSerializerOptions
            {
                Encoder= JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
                Converters =
                    {
                        new JsonDateTimeConverter("yyyy-MM-dd HH:mm:ss")
                    }
};

public PersonVerficaService(IHisRepository hisRepository, IVerificationRepository verificationRepository,IMapper mapper
            ,HisDbContext hisDbContext, IHttpContextAccessor httpContextAccessor)
        {
            this.hisRepository = hisRepository;
            this.verificationRepository = verificationRepository;
            this.mapper = mapper;
            dbContext = hisDbContext;
            httpContextAccessor = httpContextAccessor;

        }


        /// <summary>
        /// 查询未上传的住院记录
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<IEnumerable<QueryNoUploadResponse>> QueryNoUploadByExample(QueryNoUploadRequest request)
        {
            //根据条件查询住院记录
            var ioTbInPatients = await hisRepository.QueryByExampleAsync<IoTbInPatient>(s => (s.HospNo == request.HospNo || string.IsNullOrWhiteSpace(request.HospNo))
                    && (s.InTime > request.BeginTime || !request.BeginTime.HasValue)
                    && (s.InTime < request.EndTime || !request.EndTime.HasValue) && s.InsuranceCode == 111);
            ////查询已经上传成功的记录
            //var ioTbWitnessVerifications=hisRepository.QueryByExample<IoTbWitnessVerification>(s => s.ReqJson.Contains("success\":true")&&ioTbInPatients.Any(a => s.RegNo.HasValue&& a.RegNo == s.RegNo.Value));
            var ioTbWitnessVerifications =await verificationRepository.QueryByExample(request);
            List<QueryNoUploadResponse> queryNoUploadResponses = new List<QueryNoUploadResponse>();
            foreach (var item in ioTbInPatients)
            {
                List<string> infnos = new List<string>()
                {
                    "2401",
                    "2402",
                };
                
                QueryNoUploadResponse queryNoUploadResponse= mapper.Map<QueryNoUploadResponse>(item);
                
                var ioTbWitnesses=ioTbWitnessVerifications.Where(w => w.RegNo == item.RegNo);
                if (ioTbWitnesses?.Count() > 0) {
                    foreach (var ioTb in ioTbWitnesses)
                    {
                        infnos.Remove(ioTb.Infno);
                    }
                }
                if (infnos.Count() > 0)
                {
                    queryNoUploadResponse.NoUploadInfnos = infnos;
                    queryNoUploadResponses.Add(queryNoUploadResponse);
                }
            }
            return queryNoUploadResponses;
        }

        public async Task<VerificationUploadResponse> Upload(VerificationUploadRequest request, Claim claim)
        {
            _logService = new LogService();
            VerificationUploadResponse response = new VerificationUploadResponse();
            var userCode = claim.Value;
            if (userCode == null) {
                throw new Exception("未查询到当前操作员");
            }
            var worker=dbContext.SystemTbWorkers.Where(w => w.WorkerNo == userCode).FirstOrDefault();
            foreach (var item in request.UploadRecords)
            {
                foreach (var infno in item.NoUploadInfnos)
                {
                    if (infno == "2401") 
                    {
                        await Upload2401(response, worker, item);
                        //Task task = Upload2401(response, worker, item); task.Wait();
                    }
                    if (infno == "2402") 
                    {
                        await Upload2402(response, worker, item);
                        //Task task = Upload2402(response, worker, item); task.Wait();
                    }
                }
                
            }
            return response;
        }

        public async Task Upload2401(VerificationUploadResponse response, SystemTbWorker worker, Shared.Models.Request.UploadRecord item)
        {
            //try
            //{
            Thread.Sleep(3000);
                await _logService.LogAsync("Upload2401开始：");
                Shared.Models.Response.UploadRecord uploadRecord = new Shared.Models.Response.UploadRecord();
                uploadRecord.RegNo = item.RegNo;

                //Sign9001InPutNode sign = new Sign9001InPutNode()
                //{
                //    signIn = new Sign9001SignIn()
                //    {
                //        ip = "127.0.0.1",
                //        mac = "00:00:00:00",
                //        opter_no = worker.WorkerId.ToString(),
                //    },
                //};
                //VerificationRequest<Sign9001InPutNode> signRequest = new VerificationRequest<Sign9001InPutNode>()
                //{
                //    infno = "9001",
                //    msgid = "H42050300004" + DateTime.Now.ToString("yyyyMMddHHmmss") + (new Random()).Next(1000, 9999).ToString(),
                //    mdtrtarea_admvs = "420599",
                //    insuplc_admdvs = "",
                //    recer_sys_code = "103",
                //    dev_no = "",
                //    dev_safe_info = "",
                //    cainfo = "",
                //    signtype = "",
                //    infver = "V1.0",
                //    opter_type = "1",
                //    opter = worker.WorkerId.ToString(),
                //    opter_name = worker.Name,
                //    inf_time = DateTime.Now,
                //    fixmedins_code = "H42050300004",
                //    fixmedins_name = "1",
                //    sign_no = "",
                //    input = sign,
                //};
                //string signOut=string.Empty;
                //YhCom.yh_hb_call("9001", JsonSerializer.Serialize(signRequest, options), ref signOut);
                //var insurMsgResponse=JsonSerializer.Deserialize<InsurMsgResponse<Sign9001OutPutNode>>(signOut);
                //if(insurMsgResponse.infcode!=0)
                //{
                //    uploadRecord.Success = false;
                //    uploadRecord.Error = "$签到失败";
                //    (response.UploadRecords as System.Collections.IList).Add(uploadRecord);
                //    return;
                //}
                var ioTbPersonnelinfonews = await hisRepository.QueryByExampleAsync<IoTbPersonnelInfoNew>(s => s.RegNo == item.RegNo);
                await _logService.LogAsync("2401上传ioTbPersonnelinfonews结果：" + JsonSerializer.Serialize(ioTbPersonnelinfonews));

                var ioTbPersonnelinfonew = ioTbPersonnelinfonews?.FirstOrDefault();
                await _logService.LogAsync("2401上传ioTbPersonnelinfonew结果：" + JsonSerializer.Serialize(ioTbPersonnelinfonew));

                if (ioTbPersonnelinfonew == null)
                {
                    uploadRecord.Success = false;
                    uploadRecord.Error = "$查询表【IoTbPersonnelInfoNew】【RegNo={item.RegNo}】失败";
                    (response.UploadRecords as System.Collections.IList).Add(uploadRecord);
                    return;
                }

                var baseInfo = mapper.Map<Verification2401BaseInfo>(ioTbPersonnelinfonew);
                var insuInfo = mapper.Map<Verification2401InsuInfo>(ioTbPersonnelinfonew);
                var registerMdtrtinfoParams = dbContext.GetRegisterMdtrtinfo(ioTbPersonnelinfonew);
                if (registerMdtrtinfoParams == null)
                {
                    uploadRecord.Success = false;
                    uploadRecord.Error = "$执行存储【Usp_Io_registerMdtrtinfo】【RegNo={item.RegNo}】失败";
                    (response.UploadRecords as System.Collections.IList).Add(uploadRecord);
                    return;
                }
                var mdtrtInfo = mapper.Map<Verification2401MdtrtInfo>(registerMdtrtinfoParams);
                mdtrtInfo.mdtrt_id = ioTbPersonnelinfonew.MdtrtId;
                Verification2401Node node = new Verification2401Node()
                {
                    baseinfo = baseInfo,
                    insuinfo = insuInfo,
                    mdtrtinfo = mdtrtInfo,
                };
                VerificationRequest<Verification2401Node> verificationRequest = new VerificationRequest<Verification2401Node>()
                {
                    infno = "2401",
                    msgid = "H42050300004" + DateTime.Now.ToString("yyyyMMddHHmmss") + (new Random()).Next(1000, 9999).ToString(),
                    mdtrtarea_admvs = "420599",
                    insuplc_admdvs = ioTbPersonnelinfonew.InsuplcAdmdvs,
                    recer_sys_code = "103",
                    dev_no = "",
                    dev_safe_info = "",
                    cainfo = "",
                    signtype = "",
                    infver = "V1.0",
                    opter_type = "1",
                    opter = worker.WorkerId.ToString(),
                    opter_name = worker.Name,
                    inf_time = DateTime.Now,
                    fixmedins_code = "H42050300004",
                    fixmedins_name = "1",
                    sign_no = "2024090617540102-098476",
                    input = node,
                };
                var reqJson = JsonSerializer.Serialize(verificationRequest, options);
                await _logService.LogAsync("2401上传前reqJson：" + reqJson);
                IoTbWitnessVerification ioTbWitnessVerification = new IoTbWitnessVerification();
                ioTbWitnessVerification.SerialNo = GuidHelper.GenerateUnique18DigitId();
                ioTbWitnessVerification.RegNo = item.RegNo;
                ioTbWitnessVerification.Infno = verificationRequest.infno;
                ioTbWitnessVerification.ReqJson = reqJson;
                ioTbWitnessVerification.HospitalId = 10;
                ioTbWitnessVerification.CreateOn = DateTime.Now;
                ioTbWitnessVerification.CreateUserId = worker.WorkerId;
                VerificationAceRequest verificationAceRequest = new VerificationAceRequest()
                {
                    infno = verificationRequest.infno,
                    fixmedins_code = verificationRequest.fixmedins_code,
                    data = DoAES(reqJson, verificationRequest.fixmedins_code + verificationRequest.infno)
                };
                HttpClient httpClient = new HttpClient();
                httpClient.BaseAddress = new Uri("http://10.27.34.66:8080/rzhcycyljk/fmservice/");
                httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("3d903efce03347bc1dd4fe792679cc3c");
                await _logService.LogAsync("2401上传前：" + JsonSerializer.Serialize(verificationAceRequest));
                httpClient.Timeout = TimeSpan.FromSeconds(30);
                var httpResponse = await httpClient.PostAsJsonAsync("rybl", verificationAceRequest);
                await _logService.LogAsync("2401上传后：" + JsonSerializer.Serialize(httpResponse));
                if (!httpResponse.IsSuccessStatusCode)
                {
                    uploadRecord.Success = false;
                    uploadRecord.Error = httpResponse.RequestMessage.ToString();
                    (response.UploadRecords as System.Collections.IList).Add(uploadRecord);
                    return;
                }
                var verificationResponse = await httpResponse.Content.ReadFromJsonAsync<VerificationResponse<object>>();
                ioTbWitnessVerification.ResJson = JsonSerializer.Serialize(verificationResponse);
                dbContext.IoTbWitnessVerifications.Add(ioTbWitnessVerification);
                await dbContext.SaveChangesAsync();
                uploadRecord.Success = verificationResponse.success;
                uploadRecord.Error = verificationResponse.msg;
                await _logService.LogAsync("2401上传结果：" + verificationResponse.msg);
                (response.UploadRecords as System.Collections.IList).Add(uploadRecord);
            //}
            //catch (Exception e)
            //{
            //    string errorDetails = $"2401上传报错: {e.Message}\n堆栈跟踪: {e.StackTrace}";
            //    await _logService.LogAsync(errorDetails);
            //}

        }

        public async Task Upload2402(VerificationUploadResponse response, SystemTbWorker worker, Shared.Models.Request.UploadRecord item)
        {
            Shared.Models.Response.UploadRecord uploadRecord = new Shared.Models.Response.UploadRecord();
            uploadRecord.RegNo = item.RegNo;
            //Sign9001InPutNode sign = new Sign9001InPutNode()
            //{
            //    signIn = new Sign9001SignIn()
            //    {
            //        ip = "127.0.0.1",
            //        mac = "00:00:00:00",
            //        opter_no = worker.WorkerId.ToString(),
            //    },
            //};
            //VerificationRequest<Sign9001InPutNode> signRequest = new VerificationRequest<Sign9001InPutNode>()
            //{
            //    infno = "9001",
            //    msgid = "H42050300004" + DateTime.Now.ToString("yyyyMMddHHmmss") + (new Random()).Next(1000, 9999).ToString(),
            //    mdtrtarea_admvs = "420599",
            //    insuplc_admdvs = "",
            //    recer_sys_code = "103",
            //    dev_no = "",
            //    dev_safe_info = "",
            //    cainfo = "",
            //    signtype = "",
            //    infver = "V1.0",
            //    opter_type = "1",
            //    opter = worker.WorkerId.ToString(),
            //    opter_name = worker.Name,
            //    inf_time = DateTime.Now,
            //    fixmedins_code = "H42050300004",
            //    fixmedins_name = "1",
            //    sign_no = "",
            //    input = sign,
            //};
            //string signOut = string.Empty;
            //YhCom.yh_hb_call("9001", JsonSerializer.Serialize(signRequest, options), ref signOut);
            //var insurMsgResponse = JsonSerializer.Deserialize<InsurMsgResponse<Sign9001OutPutNode>>(signOut);
            //if (insurMsgResponse.infcode != 0)
            //{
            //    uploadRecord.Success = false;
            //    uploadRecord.Error = "$签到失败";
            //    (response.UploadRecords as System.Collections.IList).Add(uploadRecord);
            //    return;
            //}
            var ioTbPersonnelinfonews = await hisRepository.QueryByExampleAsync<IoTbPersonnelInfoNew>(s => s.RegNo == item.RegNo);
            var ioTbPersonnelinfonew = ioTbPersonnelinfonews?.FirstOrDefault();
            if (ioTbPersonnelinfonew == null)
            {
                uploadRecord.Success = false;
                uploadRecord.Error = "$查询表【IoTbPersonnelInfoNew】【RegNo={item.RegNo}】失败";
                (response.UploadRecords as System.Collections.IList).Add(uploadRecord);
                return;
            }
            var leaveHospitalDscginfoParams = dbContext.GetLeaveDscginfoParams(ioTbPersonnelinfonew);
            if (leaveHospitalDscginfoParams == null)
            {
                uploadRecord.Success = false;
                uploadRecord.Error = "$执行存储【Usp_Io_leaveHospitalDscginfo】【RegNo={item.RegNo}】失败";
                (response.UploadRecords as System.Collections.IList).Add(uploadRecord);
                return;
            }
            Verification2402DscgInfo dscgInfo = mapper.Map<Verification2402DscgInfo>(leaveHospitalDscginfoParams);
            Verification2402Node node = new Verification2402Node()
            {
                dscginfo= dscgInfo
            };
            VerificationRequest<Verification2402Node> verificationRequest = new VerificationRequest<Verification2402Node>()
            {
                infno = "2402",
                msgid = "H42050300004" + DateTime.Now.ToString("yyyyMMddHHmmss") + (new Random()).Next(1000, 9999).ToString(),
                mdtrtarea_admvs = "420599",
                insuplc_admdvs = ioTbPersonnelinfonew.InsuplcAdmdvs,
                recer_sys_code = "103",
                dev_no = "",
                dev_safe_info = "",
                cainfo = "",
                signtype = "",
                infver = "V1.0",
                opter_type = "1",
                opter = worker.WorkerId.ToString(),
                opter_name = worker.Name,
                inf_time = DateTime.Now,
                fixmedins_code = "H42050300004",
                fixmedins_name = "1",
                sign_no = "2024090617540102-098476",
                input = node,
            };
            var reqJson = JsonSerializer.Serialize(verificationRequest, options);
            IoTbWitnessVerification ioTbWitnessVerification = new IoTbWitnessVerification();
            ioTbWitnessVerification.SerialNo = GuidHelper.GenerateUnique18DigitId();
            ioTbWitnessVerification.RegNo = item.RegNo;
            ioTbWitnessVerification.Infno = verificationRequest.infno;
            ioTbWitnessVerification.ReqJson = reqJson;
            ioTbWitnessVerification.HospitalId = 10;
            ioTbWitnessVerification.CreateOn = DateTime.Now;
            ioTbWitnessVerification.CreateUserId = worker.WorkerId;
            VerificationAceRequest verificationAceRequest = new VerificationAceRequest()
            {
                infno = verificationRequest.infno,
                fixmedins_code = verificationRequest.fixmedins_code,
                data = DoAES(reqJson, verificationRequest.fixmedins_code + verificationRequest.infno)
            };
            HttpClient httpClient = new HttpClient();
            httpClient.BaseAddress = new Uri("http://10.27.34.66:8080/rzhcycyljk/fmservice/");
            httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("3d903efce03347bc1dd4fe792679cc3c");
            var httpResponse = await httpClient.PostAsJsonAsync("cybl", verificationAceRequest);
            if (!httpResponse.IsSuccessStatusCode)
            {
                uploadRecord.Success = false;
                uploadRecord.Error = httpResponse.RequestMessage.ToString();
                (response.UploadRecords as System.Collections.IList).Add(uploadRecord);
                return;
            }
            var verificationResponse = await httpResponse.Content.ReadFromJsonAsync<VerificationResponse<object>>();
            ioTbWitnessVerification.ResJson = JsonSerializer.Serialize(verificationResponse);
            dbContext.IoTbWitnessVerifications.Add(ioTbWitnessVerification);
            await dbContext.SaveChangesAsync();
            uploadRecord.Success = verificationResponse.success;
            uploadRecord.Error = verificationResponse.msg;
            await _logService.LogAsync("2402上传结果：" + verificationResponse.msg);
            (response.UploadRecords as System.Collections.IList).Add(uploadRecord);
        }

        private static readonly Encoding DefaultCharset = Encoding.UTF8;

        public static string DoAES(string data, string secretKey)
        {
            try
            {
                // AES requires key size of 128/192/256 bits (16/24/32 bytes).
                byte[] keyBytes = DefaultCharset.GetBytes(secretKey);

                // Content to be encrypted/decrypted
                byte[] content=DefaultCharset.GetBytes(data);
                using (Aes aes = Aes.Create())
                {
                    aes.Key = keyBytes;
                    aes.IV = Encoding.Default.GetBytes("d22b0a851e014f7b");
                    aes.Mode = CipherMode.CBC;
                    aes.Padding = PaddingMode.PKCS7;

                    ICryptoTransform cryptoTransform = aes.CreateEncryptor();

                    byte[] result = cryptoTransform.TransformFinalBlock(content, 0, content.Length);

                    return Convert.ToBase64String(result);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("AES error: " + e.Message);
                return null;
            }
        }


        public async Task<bool> DoWork()
        {
            try
            {
                // 创建请求对象
                QueryNoUploadRequest request = new QueryNoUploadRequest
                {
                    BeginTime = DateTime.Now.AddHours(-12),
                    EndTime = DateTime.Now
                };
                //根据条件查询住院记录
                var ioTbInPatients = await hisRepository.QueryByExampleAsync<IoTbInPatient>(s => (s.HospNo == request.HospNo || string.IsNullOrWhiteSpace(request.HospNo))
                        && (((s.InTime > request.BeginTime || !request.BeginTime.HasValue)
                        && (s.InTime < request.EndTime || !request.EndTime.HasValue))|| ((s.OutTime > request.BeginTime || !request.BeginTime.HasValue)
                        && (s.OutTime < request.EndTime || !request.EndTime.HasValue))) && s.InsuranceCode == 111);
                ////查询已经上传成功的记录
                //var ioTbWitnessVerifications=hisRepository.QueryByExample<IoTbWitnessVerification>(s => s.ReqJson.Contains("success\":true")&&ioTbInPatients.Any(a => s.RegNo.HasValue&& a.RegNo == s.RegNo.Value));
                var ioTbWitnessVerifications = await verificationRepository.QueryByExample(request);

                //// 查询未上传记录
                //var response = await verificationRepository.QueryByExample(request);

                //// 将 IEnumerable 转换为 List
                //List<IoTbWitnessVerification> uploadResponses = response.ToList();


                List<QueryNoUploadResponse> queryNoUploadResponses = new List<QueryNoUploadResponse>();
                foreach (var item in ioTbInPatients)
                {
                    List<string> infnos = new List<string>()
                {
                    "2401",
                    "2402",
                };

                    QueryNoUploadResponse queryNoUploadResponse = mapper.Map<QueryNoUploadResponse>(item);

                    var ioTbWitnesses = ioTbWitnessVerifications.Where(w => w.RegNo == item.RegNo);
                    if (ioTbWitnesses?.Count() > 0)
                    {
                        foreach (var ioTb in ioTbWitnesses)
                        {
                            infnos.Remove(ioTb.Infno);
                        }
                    }
                    if (infnos.Count() > 0)
                    {
                        queryNoUploadResponse.NoUploadInfnos = infnos;
                        queryNoUploadResponses.Add(queryNoUploadResponse);
                    }
                }



                if (queryNoUploadResponses.Any())
                {
                    foreach (var item in queryNoUploadResponses)
                    {
                        // 创建 UploadRecord 实例
                        Rj.PersonnelVerification.Shared.Models.Request.UploadRecord uploadRecord = new Shared.Models.Request.UploadRecord
                        {
                            RegNo = item.RegNo,
                            NoUploadInfnos = new List<string> { "2401", "2402" }
                        };

                        // 创建 VerificationUploadRequest 实例并赋值
                        var verificationRequest = new VerificationUploadRequest
                        {
                            UploadRecords = new List<Rj.PersonnelVerification.Shared.Models.Request.UploadRecord> { uploadRecord }
                        };

                        // 创建一个 Claim 对象
                        Claim claim1 = new Claim(ClaimTypes.Name, "110");

                        // 调用 Upload 方法
                        await Upload(verificationRequest, claim1); // 确保 Upload 方法是异步的
                    }

                    // 如果上传成功，返回 true
                    return true;
                }

                // 如果没有任何未上传记录，返回 false
                return false;
            }
            catch (Exception e)
            {
                // 可以选择记录异常日志
                // 例如: _logger.LogError(e, "An error occurred while doing work.");

                // 返回 false 表示操作失败
                return false;
            }
        }
    }
}
